import sys
import os

pwd = os.path.dirname(os.path.realpath(__file__))
sys.path.append(pwd + '../')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'riscv_build_dataset.settings')

import django

django.setup()

import requests
from requests.adapters import HTTPAdapter
from obs.models import obs_project, obs_package, obs_revision

from bs4 import BeautifulSoup
from config import BASE_URL
from tqdm import tqdm

# Seems that accessing this page does not need to log in
# Page URL: https://build.tarsier-infra.com/source/openEuler:22.09/mybatis/_history
# Get Package Revisions

project_name = 'openEuler:22.09'
repository_name = '20230921'
architecture_name = 'riscv64'

session = requests.Session()
session.mount('https://', HTTPAdapter(max_retries=5))
cookies = {
    '_obs_api_session': os.environ['OBS_COOKIE'],
}


def get_revision_detail(project_name: str, package_name: str, revision):
    url = f'{BASE_URL}/source/{project_name}/{package_name}?rev={revision}&expand=1'
    resp = session.get(url, cookies=cookies, timeout=2)
    # print(resp.text)
    soup = BeautifulSoup(resp.text, 'xml')
    files = {}
    for file in soup.find_all('entry'):
        file_name = file.get('name')
        if '_service:tar_scm:' in file_name:
            # Extract real file name like this: "_service:tar_scm:mybatis.yaml" -> "mybatis.yaml"
            file_name = file_name.replace('_service:tar_scm:', '')
            md5 = file.get('md5')
            size = file.get('size')
            mtime = file.get('mtime')
            files[file_name] = {'md5': md5, 'size': size, 'mtime': mtime}
    # print(files)
    return files


def get_revisions_from_url(project_name: str, package_name: str):
    # Get Revisions of a Package

    headers = {
        'Accept': 'application/xml',
        'charset': 'utf-8',
        # 'Authorization': 'Basic ' + b64credential,
    }

    response = session.get(
        f'{BASE_URL}/source/{project_name}/{package_name}/_history',
        cookies=cookies,
        headers=headers,
        timeout=2)

    # print(response.text)

    soup = BeautifulSoup(response.text, 'lxml')

    revisions = []
    for revision in soup.find_all('revision'):
        # print(revision['rev'], revision.time.contents[0], revision.user.contents[0])
        r = {
            'revision_id': revision['rev'],
            'commit_unix_time': revision.time.contents[0],
            'commit_user': revision.user.contents[0],
            'comment': revision.comment.contents[0] if revision.comment else None
        }
        revisions.append(r)

    return revisions


def save_revisions_to_db(project_name: str, package_name: str, revisions: list):
    project = obs_project.objects.get(project_name=project_name)
    package = obs_package.objects.get(project=project, package_name=package_name)
    r = obs_revision.objects.filter(project=project, package=package)
    revisions = revisions[::-1]
    for rev in revisions:
        if r.filter(revision_id=rev.get('revision_id')).exists():
            # exist
            pass
        else:
            # not exist
            obs_revision.objects.create(project=project,
                                        package=package,
                                        revision_id=rev.get('revision_id'),
                                        commit_user=rev.get('commit_user'),
                                        commit_time=rev.get('commit_time')[:-4] if rev.get('commit_time') else None,
                                        commit_unix_time=rev.get('commit_unix_time'),
                                        comment=rev.get('comment'))


if __name__ == '__main__':
    project_name = os.environ.get('OBS_PROJECT')
    repository_name = os.environ.get('OBS_REPO')
    arch_name = os.environ.get('OBS_ARCH')

    project = obs_project.objects.get(project_name=project_name)
    packages = obs_package.objects.filter(project=project)

    for package in tqdm(packages):
        # print(package.package_name)
        try:
            revisions = get_revisions_from_url(project_name, package.package_name)
            save_revisions_to_db(project_name, package.package_name, revisions)
        except Exception as e:
            print(e, file=sys.stderr)
